package cn.com.mvc.controller;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Set;

import cn.com.mvc.annotation.Controller;
import cn.com.mvc.annotation.RequestMapping;
import cn.com.mvc.utils.BeanUtils;

public class HandlerMapping {
	private Class<?> clazz;
	private HashMap<String, Method> handlers;
	private static HashMap<String, HandlerMapping> handlerMappings = new HashMap<String, HandlerMapping>();

	private HandlerMapping() {
	}

	public Class<?> getClazz() {
		return clazz;
	}

	public void setClazz(Class<?> clazz) {
		this.clazz = clazz;
	}

	public HashMap<String, Method> getHandlers() {
		return handlers;
	}

	public void setHandlers(HashMap<String, Method> handlers) {
		this.handlers = handlers;
	}

	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append("class:").append(this.clazz).append("[");
		if(this.handlers!=null&&this.handlers.size()>0){
			for (String key : this.handlers.keySet()) {
				sb.append("handler:").append(key).append(",method:")
						.append(handlers.get(key)).append(";");
			}	
		}
		sb.append("]");
		return sb.toString();
	}

	public static HashMap<String, HandlerMapping> initMappings(String[] packages) {
		for (String packagepath : packages) {
			if (!packagepath.trim().isEmpty())
				initMappingsPerPackage(packagepath);
		}
		return handlerMappings;
	}

	private static void initMappingsPerPackage(String packagepath) {
		Set<Class<?>> classes = BeanUtils.getClasses(packagepath);
		for (Class<?> clazz : classes) {
			HandlerMapping handlerMapping = new HandlerMapping();
			Controller controller = clazz.getAnnotation(Controller.class);
			if (controller != null) {
				 System.out.println(controller);
				handlerMapping.setClazz(clazz);
				HashMap<String, Method> handlers = new HashMap<String, Method>();
				Method[] methods = clazz.getDeclaredMethods();
				for (Method method : methods) {
					RequestMapping handler = method.getAnnotation(RequestMapping.class);
					if (handler != null) {
						handlers.put(handler.value(), method);
						handlerMapping.setHandlers(handlers);
					}
				}
				handlerMappings.put(controller.value(), handlerMapping);
			}
		}
	}

}
